home *** CD-ROM | disk | FTP | other *** search
- * Programmheader
- *
- * Name: PCompress
- * Author: SDI
- * Distribution: PD
- * Description: XFD external decruncher for recognising LeCrunch
- * Compileropts: -
- * Linkeropts: -
- *
- * 1.0 02.02.98 : first tries
- * 1.1 17.08.98 : some more test
- * 1.2 06.12.98 : added Expand routine, reloc handling still missing
- * 1.3 08.12.98 : finally completed stuff, uses cached SysBase
-
- INCLUDE "AINCLUDE:IncDirs.i"
- INCLUDE "lvo.i"
-
- INCLUDE "libraries/xfdmaster.i"
- INCLUDE "exec/memory.i"
-
- * head function for tests
- * INCLUDE "PrA:Projekte/xfd/Developer/Sources/ASM/xfdExeHead.a"
-
- ForeMan MOVEQ #-1,D0
- RTS
-
- DC.L XFDF_ID
- DC.W 1,0
- DC.L 0,0,Slave1
-
- DC.B "$VER: LeCrunch 1.3 (08.12.1998) by SDI",0
- N_LeCrunch DC.B 'LeCrunch',0
- EVEN
-
- Slave1 DC.L 0 ;no more slaves
- DC.W 2 ;version
- DC.W 36 ;master version
- DC.L N_LeCrunch ;name
- DC.W XFDPFF_RELOC ;flags
- DC.W 0
- DC.L RB_LeCrunch ;recog buffer
- DC.L DB_LeCrunch ;decrunch buffer
- DC.L 0 ;recog segment
- DC.L 0 ;decrunch segment
- DC.W 0,0
- DC.L $278 ;MinBufSize
-
- *************************************************************************
- * Recog buffer function: receives buffer + length in A0/D0 *
- *************************************************************************
-
- RB_LeCrunch MOVEQ #0,D0 ; False
-
- CMP.L #$000003F3,(A0)
- BNE.B .No
- CMP.L #$00EE2449,$44(A0)
- BNE.B .No
- MOVE.L #$4E750902,D1
- CMP.L $214(A0),D1
- BEQ.B .Next
- SUBQ.L #4,A0
- CMP.L $214(A0),D1
- BNE.B .No
- .Next CMP.L #$05030201,$22C(A0)
- BNE.B .No
- CMP.L #$00010011,$238(A0)
- BNE.B .No
- CMP.L #$00510091,$23C(A0)
- BNE.B .No
- CMP.L #$01110211,$240(A0)
- BNE.B .No
- CMP.L #$04110811,$244(A0)
- BNE.B .No
- CMP.L #'LEC2',$274(A0)
- BNE.B .No
- MOVEQ #1,D0 ; True
- .No RTS
-
- WORKSIZE EQU 1024 * security buffer
-
- F1_DESTLEN2 EQU $280 * offsets in source file
- F1_DESTLEN EQU $27C
- F1_SOURCELEN EQU $278
- F1_EXPCHAR EQU $284
- F1_SOURCE EQU $286
-
- *************************************************************************
- * Decrunch buffer function: receives xfdbiBufferInfo in A0 *
- *************************************************************************
-
- DB_LeCrunch MOVEM.L D2-D7/A2-A6,-(A7)
- MOVE.L A0,A5
- MOVEQ #0,D6 * return value
- MOVE.W #XFDERR_NOMEMORY,xfdbi_Error(A5)
- MOVEA.L xfdbi_SourceBuffer(A5),A4
- CMP.L #'LEC2',$274(A4)
- BEQ.B .Next
- SUBQ.L #4,A4
- .Next MOVE.L F1_DESTLEN(A4),D5
- ADD.L #$100,D5
- MOVE.L D5,D0
- MOVEQ #0,D1
- MOVE.L xfdm_ExecBase(A6),A6
- JSR _LVOAllocMem(A6)
- TST.L D0
- BEQ.B .NoMem
- MOVEA.L D0,A3
-
- LEA $100(A3),A1
- ADD.L F1_DESTLEN(A4),A1 * unpack buffer end
- MOVEA.L A1,A2
- SUBA.L F1_DESTLEN2(A4),A2 * start of unpack buffer
- MOVE.L F1_SOURCELEN(A4),D0
- ADD.L #F1_SOURCE,D0
- LEA (A4,D0.L),A0 * decrunch buffer end
- MOVE.L A6,-(A7)
- BSR.B Decrunch
- MOVE.L (A7)+,A6
-
- MOVE.W F1_EXPCHAR(A4),D0
- MOVEA.L A2,A1
- ADDA.L F1_DESTLEN2(A4),A2
- MOVEA.L A3,A0
- BSR.B Expand
-
- MOVE.L A3,A0
- BSR.W GetFileSize * returns destination size in D4
- MOVE.L D4,D0
- MOVE.L D4,xfdbi_TargetBufLen(A5)
- MOVE.L D4,xfdbi_TargetBufSaveLen(A5)
- MOVE.L xfdbi_TargetBufMemType(A5),D1
- JSR _LVOAllocMem(A6)
- MOVE.L D0,xfdbi_TargetBuffer(A5)
- BEQ.B .NoMem2
-
- MOVEA.L A3,A0
- MOVEA.L D0,A2
- BSR.W MakeFile
-
- CLR.W xfdbi_Error(A5)
- MOVEQ #1,D6 * set true
- .NoMem2 MOVE.L D5,D0
- MOVE.L A3,A1
- JSR _LVOFreeMem(A6)
- .NoMem MOVE.L D6,D0
- MOVEM.L (A7)+,D2-D7/A2-A6
- RTS
-
- *************************************************************************
- * decrunch routine - copied from file (a bit modified) *
- * *
- * gets following parameters: *
- * A0 end of source file *
- * A1 end of destination file *
- * A2 start of destination file *
- *************************************************************************
-
- Expand MOVEQ #0,D1
- .exp1 MOVE.B (A1)+,D1
- CMP.W D0,D1
- BNE.B .exp3
- MOVEQ #0,D2
- MOVE.B (A1)+,D2
- BEQ.B .exp3
- MOVE.B (A1)+,D1
- .exp2 MOVE.B D1,(A0)+
- DBRA D2,.exp2
- MOVE.B D1,(A0)+
- .exp3 MOVE.B D1,(A0)+
- CMPA.L A0,A2
- BGT.B .exp1
- RTS
-
- Decrunch MOVEQ #-$80,D3
- Decrunch2 BSR.B Func1
- BCC.B Func3
- BSR.B Func1
- BCC.B .DecEnd
- MOVEQ #3,D0
- MOVEQ #8,D2
- .DecLoop SUBQ.W #2,D2
- MOVE.B Data1B(PC,D0.W),D4
- BSR.B Func2
- CMP.W Data2W(PC,D2.W),D1
- DBNE D0,.DecLoop
- MOVE.B Data3B(PC,D0.W),D2
- ADD.W D1,D2
- .DecLoop2 MOVE.B -(A0),-(A1)
- DBRA D2,.DecLoop2
- .DecEnd MOVE.B -(A0),-(A1)
- CMPA.L A1,A2
- BLE.B Func3
- RTS
-
- Func1 ADD.B D3,D3
- BNE.B .F1_1
- MOVE.B -(A0),D3
- ADDX.B D3,D3
- .F1_1 RTS
-
- Func2 MOVEQ #0,D1
- .F2_1 BSR.B Func1
- ADDX.W D1,D1
- SUBQ.B #1,D4
- BPL.B .F2_1
- RTS
-
- Func3 MOVEQ #4,D0
- .F3_1 BSR.B Func1
- BCC.B .F3_2
- SUBQ.W #1,D0
- BNE.B .F3_1
- .F3_2 CLR.W D1
- MOVE.B Data4B(PC,D0.W),D4
- BMI.B .F3_3
- BSR.B Func2
- .F3_3 MOVE.B Data5B(PC,D0.W),D0
- ADD.W D1,D0
- MOVEQ #2,D4
- BSR.B Func2
- MOVE.L D1,D2
- MOVE.B Data6B(PC,D2.W),D4
- ADD.W D2,D2
- BSR.B Func2
- ADD.W Data7W(PC,D2.W),D1
- MOVEA.L A1,A6
- ADDA.L D1,A6
- .F3_4 MOVE.B -(A6),-(A1)
- DBRA D0,.F3_4
- CMPA.L A1,A2
- BLE.B Decrunch2
- RTS
-
- Data1B DC.B 9,2,1,0
- Data2W DC.W $03FF,7,3,1
- Data3B DC.B $B,4,1,0
- Data4B DC.B 9,1,0,-1,-1
- Data5B DC.B 9,5,3,2,1
- Data6B DC.B 3,5,5,6,7,8,9,$A
- Data7W DC.W $001,$011,$051,$091,$111,$211,$411,$811
-
- * gets target in A0
- GetFileSize MOVEQ #0,D3 * current hunk number
- MOVE.L 8(A0),D7 * number of hunks
- MOVE.L D7,D4
- LSL.L #2,D4
- ADD.L #20,D4 * D4 holds size of destination file
- LEA (A0,D4.L),A0
- .MainLoop MOVE.L (A0)+,D0
- ADDQ.L #4,D4
- CMP.W #$03E9,D0
- BEQ.B .Code
- CMP.W #$03EA,D0
- BEQ.B .Code
- CMP.W #$03EB,D0
- BEQ.B .BSS
- CMP.W #$03EC,D0
- BEQ.B .Reloc
- CMP.L D3,D7
- BGT.B .MainLoop
- RTS
-
- .Code MOVE.L (A0)+,D0
- LSL.L #2,D0
- ADDQ.L #4,D4
- ADD.L D0,D4 * update size
- LEA (A0,D0),A0 * skip data
- ADDQ.L #1,D3 * next hunk
- BRA.B .MainLoop
-
- .BSS ADDQ.L #1,D3 * next hunk
- ADDQ.L #4,A0 * skip size information
- ADDQ.L #4,D4 * update size
- BRA.B .MainLoop
-
- .Reloc MOVE.B (A0)+,D1
- LSL.W #8,D1
- MOVE.B (A0)+,D1
- CMP.W #-1,D1
- BNE.B .DoRelHunk
- ADDQ.L #4,D4 * add space for finishing 0 in destination
- MOVE.L A0,D0 * 0xFFFF the end of hunk list
- ADDQ.L #3,D0
- ANDI.W #-4,D0 * round to long
- MOVEA.L D0,A0
- BRA.B .MainLoop * end the reloc work
-
- .DoRelHunk MOVE.B (A0)+,D0 * byte 4
- LSL.W #8,D0
- MOVE.B (A0)+,D0 * byte 3
- SWAP D0
- MOVE.B (A0)+,D0 * byte 2
- LSL.W #8,D0
- MOVE.B (A0)+,D0 * byte 1
- ADD.L #12,D4 * numrelocs, related hunk and one entry added
- .RLoop MOVE.B (A0)+,D0 * get next byte
- BEQ.B .Reloc * zero --> finished that hunk, take next
- CMP.B #1,D0 * was == 01 ?
- BEQ.B .RLoop * yes -> loop again
- ADDQ.L #4,D4 * added one entry more
- BRA.B .RLoop * do next data
-
- * gets source in A0
- * gets destination in A2
- MakeFile MOVE.L 8(A0),D7 * number of hunks
- MOVEQ #0,D3 * current hunk number
- MOVE.L D7,D0
- ADDQ.L #4,D0
- .CopyHead MOVE.L (A0)+,(A2)+
- DBRA D0,.CopyHead
- .MainLoop MOVE.L (A0)+,D0
- MOVE.L D0,(A2)+
- CMP.W #$03E9,D0
- BEQ.B .Code
- CMP.W #$03EA,D0
- BEQ.B .Code
- CMP.W #$03EB,D0
- BEQ.B .BSS
- CMP.W #$03EC,D0
- BEQ.B .Reloc
- CMP.L D3,D7
- BGT.B .MainLoop
- RTS
-
- .Code MOVE.L (A0)+,D0
- MOVE.L D0,(A2)+
- BEQ.B .SkipCode
- .CopyCode MOVE.L (A0)+,(A2)+
- SUBQ.L #1,D0
- BNE.B .CopyCode
- .SkipCode ADDQ.L #1,D3 * next hunk
- BRA.B .MainLoop
-
- .BSS ADDQ.L #1,D3 * next hunk
- MOVE.L (A0)+,(A2)+
- BRA.B .MainLoop
-
- .Reloc MOVEQ #0,D1
- MOVE.B (A0)+,D1
- LSL.W #8,D1
- MOVE.B (A0)+,D1
- CMP.W #-1,D1
- BNE.B .DoRelHunk
- CLR.L (A2)+ * add finishing 0 in destination
- MOVE.L A0,D0 * 0xFFFF the end of hunk list
- ADDQ.L #3,D0
- ANDI.W #-4,D0 * round to long
- MOVEA.L D0,A0
- BRA.B .MainLoop * end the reloc work
-
- .DoRelHunk MOVE.B (A0)+,D0 * byte 4
- LSL.W #8,D0
- MOVE.B (A0)+,D0 * byte 3
- SWAP D0
- MOVE.B (A0)+,D0 * byte 2
- LSL.W #8,D0
- MOVE.B (A0)+,D0 * byte 1
- MOVE.L A2,A4 * store pointer
- ADDQ.L #4,A2
- MOVE.L D1,(A2)+
- MOVE.L D0,(A2)+
- MOVE.L D0,D2
- MOVEQ #1,D1 * number of relocs
- .RLoop MOVEQ #0,D0
- MOVE.B (A0)+,D0 * get next byte
- BEQ.B .RelocEnd * zero --> finished that hunk, take next
- LSL.L #1,D0 * double it
- ADD.L D0,D2
- CMP.W #2,D0 * was == 01 ?
- BNE.B .StoreReloc * no -> call store func
- ADD.L #$1FA,D2 * yes -> add 0x1FA
- BRA.B .RLoop * and read next data
- .StoreReloc MOVE.L D2,(A2)+
- ADDQ.L #1,D1
- BRA.B .RLoop
-
- .RelocEnd MOVE.L D1,(A4) * store numrelocs
- BRA.B .Reloc
- END
-